package hyl.ext.pipe;

import java.io.IOException;
import java.nio.file.WatchService;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.alibaba.fastjson.JSONObject;
import java.nio.file.*;

import static java.nio.file.StandardWatchEventKinds.*;

import hyl.core.AIni;
import hyl.core.conf.MyConfig;

public class CCConfig {
	private static final Logger log = LoggerFactory.getLogger(CCNode.class);
	static CCConfig ccc = null;
	String zk_server = null;
	String sms_server = null;
	String sms_who = null;
	String email = null;
	String frameconfig = null;

	Map<String, CCFrame> bms = new HashMap<>();

	public static CCConfig getInstance() throws Exception {

		// 读取ini配置
		if (null == ccc) {
			ccc = new CCConfig();
			ccc.readIniConfig();
			ccc.readModeljson();
		}
		return ccc;
	}

	private void readIniConfig() {
		Map<String, String> mm = MyConfig.loadIni("cc.ini", AIni.charset);
		ccc.zk_server = mm.get("ZK.SERVER");
		ccc.sms_server = mm.get("SMS.SERVER");
		ccc.sms_who = mm.get("SMS.WHO");
		ccc.email = mm.get("EMAIL");
		ccc.frameconfig = mm.get("FRAME.CONFIG");

	}

	private void readModeljson() throws Exception {
		try {
			JSONObject jo = MyConfig.loadJsonObj(ccc.frameconfig,AIni.charset);
			bms.clear();
			for (String group : jo.keySet()) {
				JSONObject jo2 = jo.getJSONObject(group);
				String pack = jo2.getString("JAR");
				CCFrame bm = new CCFrame(ccc //
						, jo2.getString("生产配置") // 必填
						, jo2.getString("消费配置")// 必填
						// , MyFun.obj2Int(jo2.get("消费人数"), 1)// 必填
						, group // =配置项的key 用于分组消费者和生产者 必填
						, pack // 如果为空从已有的类环境中提取类 ,如果不为空 从外部包中取类
						, jo2.getString("主类") // 必填
						, jo2.getBooleanValue("禁用")); // 如果不填 默认不启用

				JSONObject jo3 = jo2.getJSONObject("来源");

				for (Entry<String, Object> 来源 : jo3.entrySet()) {
					JSONObject jo4 = (JSONObject) 来源.getValue();
					String fun = jo4.getString("方法");
					String 去向 = jo4.getString("去向");
					CCNode nd = new CCNode(bm, 来源.getKey(), 去向, fun);
					bm.addNode(nd);
				}

				bms.put(group, bm);
			}
		} catch (IOException e) {
			e.printStackTrace();
		}

	}

	public CCFrame getFrame(String key) {
		return bms.get(key);
	}

	private WatchService watcher;

//监控配置文件动态变化
	public void watcherDir(String directory) throws IOException, InterruptedException {
		watcher = FileSystems.getDefault().newWatchService();
		Path path = Paths.get(directory);
		path.register(watcher, ENTRY_CREATE, ENTRY_MODIFY);
		Path path1 = Paths.get(directory, "cc");
		path1.register(watcher, ENTRY_CREATE, ENTRY_MODIFY);
		Path path2 = Paths.get(directory, "mq");
		path2.register(watcher, ENTRY_CREATE, ENTRY_MODIFY);
		while (true) {
			WatchKey key = watcher.take();
			for (WatchEvent<?> event : key.pollEvents()) {
				WatchEvent.Kind<?> kind = event.kind();
				if (kind == OVERFLOW) {// 事件可能lost or discarded
					continue;
				}
				Path fileName = (Path) event.context();
				log.info("配置文件被修改 :%s%n", kind.name(), fileName);
			}
			// 这行必须有，不然不能连续地监控目录
			if (!key.reset()) {
				log.error("无法监控配置文件变化了");
				break;

			}
		}
	}

}
